﻿using System;
using log4net;
using System.IO;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Unity;
using System.Linq;
using log4net.Core;
using System.Windows;
using System.Threading;
using Prism.Modularity;
using System.Reflection;
using System.Diagnostics;
using System.Globalization;
using FrameWork.Core.Log4Net;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using FrameWork.Core.Adapter.Protocol;
using FrameWork.Core.Adapter;
using FrameWork.Core;
using FrameWork.Language;
using FrameWork.Services;
using FrameWork.Core.Infrastructure;
using FrameWork.Core.Extend;
using FrameWork.Data.Interface;
using FrameWork.Data.Mapping;
using Microsoft.Extensions.Configuration;
using System.Windows.Media.Animation;

namespace AncheStart
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {
        #region ___字段___

        private static Mutex mutex;

        ///<summary>
        /// 该函数设置由不同线程产生的窗口的显示状态
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="cmdShow">指定窗口如何显示。查看允许值列表，请查阅ShowWlndow函数的说明部分</param>
        /// <returns>如果函数原来可见，返回值为非零；如果函数原来被隐藏，返回值为零</returns>
        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

        /// <summary>
        ///  该函数将创建指定窗口的线程设置到前台，并且激活该窗口。键盘输入转向该窗口，并为用户改各种可视的记号。
        ///  系统给创建前台窗口的线程分配的权限稍高于其他线程。
        /// </summary>
        /// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
        /// <returns>如果窗口设入了前台，返回值为非零；如果窗口未被设入前台，返回值为零</returns>
        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        #endregion ___字段___

        #region ____程序启动____

        /// <summary>
        /// 程序启动
        /// </summary>
        /// <param name="e"></param>
        protected override void OnStartup(StartupEventArgs e)
        {
            try
            {

                Timeline.DesiredFrameRateProperty.OverrideMetadata(
              typeof(Timeline),
              new FrameworkPropertyMetadata { DefaultValue = 144 }
              );

                //程序退出弹窗关闭
                //Current.ShutdownMode = ShutdownMode.OnMainWindowClose;

                string exeName = "AncheStart";
                bool createdNew = SingleProgramHelper.CheckSingleProgram(exeName, ref mutex, Environment.Exit, ShowWindowAsync, SetForegroundWindow);
                //if (createdNew == false)
                //{
                //    return;
                //}
                base.OnStartup(e);

                //UI线程未捕获异常处理事件
                this.DispatcherUnhandledException += App_DispatcherUnhandledException;
                //Task线程内未捕获异常处理事件
                TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
                //非UI线程未捕获异常处理事件
                AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            }
            catch (Exception ex)
            {
                //日志记录
                LogHelper.Log.Error(ex);
                WriteTxt(ex.Message);
            }
        }

        /// <summary>
        /// 程序退出
        /// </summary>
        /// <param name="e"></param>
        protected override void OnExit(ExitEventArgs e)
        {
            //关闭DataSee
            try
            {
                Process[] myProgress;
                myProgress = Process.GetProcesses();          //获取当前启动的所有进程
                foreach (Process p in myProgress)            //关闭当前启动的Excel进程
                {
                    if (p.ProcessName == ProcessNameConfig.DataSee)          //通过进程名来寻找
                    {
                        p.Kill();
                    }
                }
            }
            catch (Exception ex)
            {
            }
            base.OnExit(e);
            Environment.Exit(0);
        }

        #endregion ____程序启动____

        #region ____Prism框架___

        /// <summary>
        /// 启动首页
        /// </summary>
        /// <returns></returns>
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        protected override void OnInitialized()
        {
            base.OnInitialized();
        }

        /// <summary>
        /// 重写初始化容器，添加日志拦截器
        /// </summary>
        /// <returns></returns>
        protected override IContainerExtension CreateContainerExtension()
        {
       
            return base.CreateContainerExtension();

         
        }

        /// <summary>
        /// 注入
        /// </summary>
        /// <param name="containerRegistry"></param>
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //日志注入
            containerRegistry.RegisterInstance<ILog>(LogHelper.Log);

       
       
           

        }

        /// <summary>
        /// 制定文件夹路径方式注入子模块
        /// </summary>
        /// <returns></returns>
        protected override IModuleCatalog CreateModuleCatalog()
        {
            return new DirectoryModuleCatalog() { ModulePath = @".\Plugins\" };
        }

        /// <summary>
        /// 默认界面和Vm映射规则
        /// </summary>
        protected override void ConfigureViewModelLocator()
        {
            base.ConfigureViewModelLocator();

            ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(viewType =>
            {
                var viewName = viewType.FullName;
                viewName = viewName.Replace(".Views.", ".ViewModels.");
                var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
                //var suffix = viewName.EndsWith("View") ? "Model" : "Vm";
                //var viewModelName = string.Format(CultureInfo.InvariantCulture, "{0}{1}", viewName, suffix);
                var suffix = viewName.EndsWith("View") ? (viewType.Namespace.Replace("Views", "ViewModels.") + viewType.Name.Replace("View", "Vm")) : (viewName + "Vm");
                var viewModelName = string.Format(CultureInfo.InvariantCulture, "{0}", suffix);

                var assembly = viewType.GetTypeInfo().Assembly;
                var type = assembly.GetType(viewModelName, true);

                return type;
            });

            IConfiguration configuration = ConfigurationHelper.GetConfiguration("AppSettings.json");
            ConfigurationHelper.Configuration = configuration;
        }

        #endregion ____Prism框架___

        #region ___全局异常处理___

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                System.Windows.MessageBox.Show("程序运行错误", e.ToString(), MessageBoxButton.OK, MessageBoxImage.Hand);
                //LogHelper.Log.Error($"线程异常：{e.ToString()}");
            }
            catch
            { }
        }

        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            try
         {
                System.Windows.MessageBox.Show("UI线程运行错误", e.ToString(), MessageBoxButton.OK, MessageBoxImage.Hand);
                e.Handled = true;
                //LogHelper.Log.Error($@"未捕获主线程异常信息：{e.Exception.Message}
                //                                   异常对象：{e.Exception.Source}
                //                                   触发方法：{e.Exception.TargetSite}
                //                                   异常堆栈：{e.Exception.StackTrace.Trim()}");
            }
            catch
            { }
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            try
            {
                System.Windows.MessageBox.Show("Task线程运行错误", e.ToString(), MessageBoxButton.OK, MessageBoxImage.Hand);
                e.SetObserved();
                //LogHelper.Log.Error($@"未处理Task异常信息：{e.Exception.Message}
                //                                 异常对象：{e.Exception.Source}
                //                                 触发方法：{e.Exception.TargetSite}
                //                                 异常堆栈：{e.Exception.StackTrace?.Trim()}
                //                                 异常信息：{e.Exception}");
            }
            catch
            { }
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="message"></param>
        private void WriteTxt(string message)
        {
            try
            {
                var fileName = @"1.txt";
                if (System.IO.File.Exists(fileName) == false)
                {
                    FileStream fs = System.IO.File.Create(fileName);
                    fs.Close(); fs.Dispose();
                }
                using (StreamWriter sr = new StreamWriter(fileName))
                {
                    sr.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ff")}:{message}");
                }
            }
            catch (Exception ex)
            {
                LogHelper.Log.Error(ex);
            }
        }

        #endregion ___全局异常处理___
    }
}